package wei.xinya.core.lambda;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Formatter;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
 * Java8内置的四大核心函数式接口
 */
class Test {
    public static void main(String[] args) {
        new Test().test4();
    }


    // Consumer<T>  消费型接口（一个参数，无返回值）

    public void test1() {
        happy((x) -> System.out.println("每次出去玩，花费" + x + "元"));    // 每次出去玩，花费1000.0元
    }

    private void happy(Consumer<Double> consumer) {
        consumer.accept((double) 1000);
    }


    // Supplier<T>  供给型接口（无参数，一个返回值）

    public void test2() {
        List<Integer> list = getNumberList(() -> (int) (Math.random() * 100));
        System.out.println(list);
    }

    // 需求：产生指定个数的整数，并放入集合中
    private List<Integer> getNumberList(Supplier<Integer> supplier) {
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Integer a = supplier.get();
            list.add(a);
        }
        return list;
    }


    // Function<T, R>  函数型接口（一个参数，一个返回值）

    public void test3() {
        int x = (Integer) compute(5, value -> value * value);
        int y = (Integer) compute(6, value -> value + value);
        int z = (Integer) compute(7, value -> value - 1);

        Formatter formatter = new Formatter(System.out);
        formatter.format("x = %d, y = %d, z = %d", x, y, z);

        System.out.println();
        System.out.println("-----------------------------");

        int composeVal = compute_compose(5, value -> value * value, value -> value + value);
        int valCompose = compute_compose(10, value -> value + value, value -> value * value);
        formatter.format("composeVal = %d , valCompose = %d", composeVal, valCompose);

        System.out.println();
        System.out.println("-----------------------------");

        int andThenVal = compute_andThen(2, value -> value * value, value -> value + value);
        int valAndThen = compute_andThen(1, value -> value + value, value -> value * value);
        formatter.format("andThenVal = %d , valAndThen = %d", andThenVal, valAndThen);

        System.out.println();
    }

    //默认方式
    private Object compute(int a, Function<Integer, Integer> function) {
        return function.apply(a);
//        return Function.identity().apply(a);
    }

    //compose 组合 before  后面先执行，执行结果作为前func的参数
    private int compute_compose(int a, Function<Integer, Integer> function, Function<Integer, Integer> function1) {
        return function.compose(function1).apply(a);
    }

    //andThen 接着执行 after 按先后顺序执行，前一个func的结果作为后一个func的参数
    private int compute_andThen(int a, Function<Integer, Integer> function, Function<Integer, Integer> function1) {
        return function.andThen(function1).apply(a);
    }

    // Predicate<T>  断言型接口

    public void test4() {
        List<String> stringList = Arrays.asList("hello", "ok", "china");
        List<String> list = filterString(stringList, (x) -> x.length() > 3);
        System.out.println(list);    // [hello, china]
    }

    //需求：将满足条件的字符串放入集合中
    private List<String> filterString(List<String> list, Predicate<String> predicate) {
        List<String> stringList = new ArrayList<>();
        list.forEach(s -> {
            if (predicate.test(s)) {
                stringList.add(s);
            }
        });
        return stringList;
    }

}
